package com.sys.util;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.FastDateFormat;

public class DateUtil {
	
	
	/** 日期格式yyyy-MM-dd字符串常量 */  
    private static final String DATE_FORMAT = "yyyy-MM-dd";	
    
    private static final String DATE_FORMAT_HIVE = "yyyyMMdd";
	
	public static FastDateFormat fdf = FastDateFormat.getInstance(DATE_FORMAT);
	
	private static final String[] PARSE_PATTERNS = {"yyyy-MM-dd","MM-dd"};
	/**
	 * 初始化日期
	 * @param date
	 */
	private static Date initDate(Date date){
		if(date == null){
			return new Date();
		}
		return date;
	}

	/**
	 * 获取昨天的日期
	 * @param date
	 * @return
	 */
	public static Date getYesterday(Date date){
		return truncate(DateUtils.addDays(initDate(date), -1));
	}
	/**
	 * 获取上周的今日
	 * @param date
	 * @return
	 */
	public static Date getLastWeekDay(Date date){
		return truncate(DateUtils.addWeeks(initDate(date), -1));
	}
	/**
	 * 获取截短的日期
	 * @param date
	 * @return
	 */
	public static Date truncate(Date date){
		return DateUtils.truncate(date, Calendar.DATE);
	}
	/**
	 * 获取默认的时间
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static List<Date> getBetweenDays(Date startDate,Date endDate){
		List<Date> result = null;
		if(startDate == null||endDate == null){
			endDate = getYesterday(null);
			startDate = DateUtils.addDays(endDate, -29);			
		}
		if(endDate.after(startDate)){
			int s = (int)((endDate.getTime() - startDate.getTime())/DateUtils.MILLIS_PER_DAY);
			result = new ArrayList<Date>(s+1);
			result.add(startDate);
			for(int i=1;i<=s;i++){
				result.add(DateUtils.addDays(startDate, i));
			}
		}
		else{			
			result = new ArrayList<Date>(0);
		}
		return result;
	}
	/**
	 * 获取默认的时间
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static List<String> getStringBetweenDays(Date startDate,Date endDate){
		List<String> result = null;
		if(startDate == null||endDate == null){
			endDate = getYesterday(null);
			startDate = DateUtils.addDays(endDate, -29);			
		}
		if(endDate.after(startDate)){
			int s = (int)((endDate.getTime() - startDate.getTime())/DateUtils.MILLIS_PER_DAY);
			result = new ArrayList<String>(s+1);
			result.add(dateFormat(startDate));
			for(int i=1;i<=s;i++){
				result.add(dateFormat(DateUtils.addDays(startDate, i)));
			}
		}
		else{			
			result = new ArrayList<String>(0);
		}
		return result;
	}
	/**
	 * 获取date所在周的开始日期
	 * @param date
	 * @return
	 */
	public static Date getThisWeekStart(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(initDate(date));
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		return truncate(calendar.getTime());
	}
	/**
	 * 获取date所在周的结束日期
	 * @param date
	 * @return
	 */
	public static Date getThisWeekEnd(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(initDate(date));
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		calendar.add(Calendar.DAY_OF_WEEK, 6);
		return truncate(calendar.getTime());
	}
	/**
	 * 获取当月的开始日期
	 * @param date
	 * @return
	 */
	public static Date getThisMonthStart(Date date){
		initDate(date);
		return DateUtils.truncate(date, Calendar.MONTH);
	}
	/**
	 * 判断两个日期的年月日部分是否相等
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static boolean isSameDay(Date date1,Date date2){
		return DateUtils.isSameDay(date1, date2);
	}
	/**
	 * 获取当月的结束日期
	 * @param date
	 * @return
	 */
	public static Date getThisMonthEnd(Date date){
		initDate(date);
		Date nextMonthStart = DateUtils.ceiling(date, Calendar.MONTH);
		return truncate(DateUtils.addDays(nextMonthStart, -1));
	}
	/**
	 * 获取上月的开始日期
	 * @param date
	 * @return
	 */
	public static Date getLastMonthStart(Date date){
		initDate(date);
		Date lastMonthDay = DateUtils.addMonths(date, -1);
		return truncate(DateUtils.truncate(lastMonthDay, Calendar.MONTH));
	}
	/**
	 * 时间格式化
	 * @param format
	 * @param date
	 * @return
	 */
	public static String dateFormat(String format, Date date) {
		initDate(date);
		return DateFormatUtils.format(date, format);
	}
	/**
	 * 时间格式化
	 * @param date
	 * @return
	 */
	public static String dateFormat(Date date) {
		return fdf.format(initDate(date));
	}
	
	/**
	 * 格式化字符串的时间为Date
	 * @param day
	 * @param parsePatterns
	 * @return
	 * @throws ParseException
	 */
	public static Date parseDate(String day,String[] parsePatterns) throws ParseException{
		return DateUtils.parseDate(day, parsePatterns);
	}
	/**
	 * 用默认的样式格式化字符串的时间为Date
	 * @param day
	 * @return
	 * @throws ParseException
	 */
	public static Date parseDate(String day) throws ParseException{
		return DateUtils.parseDate(day, PARSE_PATTERNS);
	}

	/**
	 * 判断date是否在startDate,endDate区间内
	 * @param startDate
	 * @param endDate
	 * @param date
	 * @return
	 */
	public static boolean isBeteenTwoDate(String startDate, String endDate, String date) {

		if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate) || StringUtils.isEmpty(date)) {
			return false;
		}
		if (startDate.compareToIgnoreCase(date) <= 0 && endDate.compareToIgnoreCase(date) >= 0) {
			return true;
		}

		return false;
	}
	/**
	 * 判断date是否在startDate,endDate区间内
	 * @param startDate
	 * @param endDate
	 * @param date
	 * @return
	 */
	public static boolean isBeteenTwoDate(Date startDate,Date endDate,Date date){
		String startDay = DateUtil.dateFormat(startDate);
		String endDay = DateUtil.dateFormat(endDate);
		String day = DateUtil.dateFormat(date);
		if(startDay.compareTo(day)<=0 && day.compareTo(endDay)<=0){
			return true;
		}
		return false;		
	}

	

	/**
	 * 将短时间格式字符串转换为时间 yyyy-MM-dd
	 * 
	 * @param strDate
	 * @return
	 */
	public static Date strToDate(String strDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(strDate, pos);
		return strtodate;
	}

	/**
	 * 两个时间之间的天数
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long getDays(String date1, String date2) {
		if (date1 == null || date1.equals(""))
			return 0;
		if (date2 == null || date2.equals(""))
			return 0;
		// 转换为标准时间
		SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
		java.util.Date date = null;
		java.util.Date mydate = null;
		try {
			date = myFormatter.parse(date1);
			mydate = myFormatter.parse(date2);
		} catch (Exception e) {
		}
		long day = (mydate.getTime() - date.getTime()) / (24 * 60 * 60 * 1000);
		return day;
	}

	/**
	 * 获取当前日期的前几天或者后几天日期
	 * @param day 天数 负数代表前几天，正数代表后几天
	 * @return
	 */
	public static Date getDateByDay(int day){
		// 获取当前日期
		Calendar date = Calendar.getInstance();
		date.set(Calendar.DATE, date.get(Calendar.DATE)+day);   		
		String strDate = new SimpleDateFormat("yyyy-MM-dd").format(date.getTime());
		// 将字符串日期转换成 java.sql.Date 日期类型
		return java.sql.Date.valueOf(strDate);
	}
	
	public static List<java.sql.Date> getBetween(java.sql.Date startDate,java.sql.Date endDate){
		List<java.sql.Date> result = new ArrayList<java.sql.Date>();
		long day = (endDate.getTime() - startDate.getTime())/(24 * 60 * 60 * 1000);
		result.add(startDate);
		for(int i=1;i<day;i++){
			long time = (long)(i*(24L * 60L * 60L * 1000L))+startDate.getTime();
			java.sql.Date date = new java.sql.Date(time);
			result.add(date);
		}
		result.add(endDate);
		return result;
	}
	/**
	 * 判断date1是否在date2之前,如果date1小于或等于date2,则返回ture,否则返回false
	 * @param date1
	 * @param date2
	 */
	public static boolean before(Date date1,Date date2){
		if(date2.compareTo(date1)<0){
			return false;
		}
		return true;
	}
	
	public static void main(String[] args) throws ParseException {
		Date date = parseDate("2013-05-17");
		System.out.println(DateUtil.dateFormat(DateUtils.addDays(date, -106)));
		
	}
}

